/*******************************************************************************
 * Copyright (c) 2010 European Software Institute - Tecnalia.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Author - Adri�n Noguero (adrian.noguero@esi.es)
 *     
 *******************************************************************************/

package es.esi.gemde.modelvalidator.ui.dialogs;

import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import es.esi.gemde.core.CorePlugin;
import es.esi.gemde.core.resources.ExtendedWizardDialog;
import es.esi.gemde.core.resources.IGemdeResource.ResourceType;
import es.esi.gemde.modelvalidator.ModelValidatorPlugin;
import es.esi.gemde.modelvalidator.service.IBatchValidation;
import es.esi.gemde.modelvalidator.service.IModelValidatorConstraint;
import es.esi.gemde.modelvalidator.service.IModelValidatorService;
import es.esi.gemde.modelvalidator.ui.wizards.ValidationCreationWizard;


/**
 * A dialog to manage the Batch Validations Repository
 *
 * @author Adrian Noguero (adrian.noguero@tecnalia.com)
 * @version 1.0.4
 * @since 1.0
 *
 */
public class ValidationManagementDialog extends Dialog {

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("GEMDE Validations Repository Viewer");
		newShell.setImage(CorePlugin.getImage(CorePlugin.VALIDATION_REPOSITORY_ICON));
		newShell.setSize(400, 300);
	}

	private TreeViewer validationViewer;
	private Button createButton;
	private Button editButton;
	private Button removeButton;
	private IModelValidatorService server;
	
	private SelectionListener createButtonListener = new SelectionListener () {

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			// Not needed
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			ValidationCreationWizard wizard = new ValidationCreationWizard();
			WizardDialog dialog = new ExtendedWizardDialog(getShell(), wizard, CorePlugin.getImage(CorePlugin.VALIDATION_REPOSITORY_ICON));
			int result = dialog.open();
			
			if (result == Dialog.OK) {
				try {
					server.addBatchValidation(wizard.getCreatedValidation());
				}
				catch (IllegalArgumentException ex) {
					MessageDialog.openWarning(new Shell(), "Couldn't create the validation", "The provided validation name is already in use.");
				}
			}
			updateValidationData();
		}
		
	};
	
	private SelectionListener editButtonListener = new SelectionListener () {

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			// Not needed
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			if (editButton.isEnabled()) {
				Object selection = ((StructuredSelection)validationViewer.getSelection()).getFirstElement();
				if (selection instanceof IBatchValidation) {
					ValidationCreationWizard wizard = new ValidationCreationWizard(((IBatchValidation)selection).getName(), ((IBatchValidation)selection).getSelectedConstraints());
					WizardDialog dialog = new ExtendedWizardDialog(getShell(), wizard, CorePlugin.getImage(CorePlugin.VALIDATION_REPOSITORY_ICON));
					int result = dialog.open();
					
					if (result == Dialog.OK) {
						server.removeBatchValidation(((IBatchValidation)selection).getName());
						server.addBatchValidation(wizard.getCreatedValidation());
					}
					updateValidationData();
				}
			}
		}
		
	};
	
	private SelectionListener removeButtonListener = new SelectionListener () {

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			// Not needed
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			if (removeButton.isEnabled()) {
				Object selection = ((StructuredSelection)validationViewer.getSelection()).getFirstElement();
				if (selection instanceof IBatchValidation) {
					server.removeBatchValidation(((IBatchValidation)selection).getName());
				}
				updateValidationData();
			}
		}
		
	};
	
	private ISelectionChangedListener constraintListener = new ISelectionChangedListener() {
		
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			Object selection = ((StructuredSelection)validationViewer.getSelection()).getFirstElement();
			if (selection instanceof IBatchValidation) {
				if (!((IBatchValidation)selection).getResourceType().equals(ResourceType.NORMAL)) {
					removeButton.setEnabled(false);
					editButton.setEnabled(false);
				}
				else {
					removeButton.setEnabled(true);
					editButton.setEnabled(true);
				}
			}
			else {
				removeButton.setEnabled(false);
				editButton.setEnabled(false);
			}
			
			if (selection instanceof IModelValidatorConstraint) {
				validationViewer.getTree().setToolTipText(((IModelValidatorConstraint)selection).getBody());
			}
			else {
				validationViewer.getTree().setToolTipText("");
			}
		}
	};
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		// Only create an OK button
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite topPanel = (Composite)super.createDialogArea(parent);
		
		topPanel.setSize(600, 400);

		GridLayout layout = (GridLayout)topPanel.getLayout();
		layout.numColumns = 4;
		
		validationViewer = new TreeViewer(topPanel, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		GridData constraintViewerData = new GridData(GridData.FILL_BOTH);
		constraintViewerData.horizontalSpan = 4;
		validationViewer.getTree().setLayoutData(constraintViewerData);
		updateValidationData();
		
		Label emptyLabel = new Label(topPanel, SWT.NONE);
		GridData emptyLabelData = new GridData(GridData.FILL_HORIZONTAL);
		emptyLabelData.horizontalSpan = 1;
		emptyLabel.setText("");
		emptyLabel.setLayoutData(emptyLabelData);
		
		createButton = new Button(topPanel, SWT.PUSH | SWT.CENTER);
		GridData createButtonData = new GridData(GridData.FILL_HORIZONTAL);
		createButtonData.horizontalSpan = 1;
		createButton.setLayoutData(createButtonData);
		createButton.setText("Create");
		
		editButton = new Button(topPanel, SWT.PUSH | SWT.CENTER);
		GridData editButtonData = new GridData(GridData.FILL_HORIZONTAL);
		editButtonData.horizontalSpan = 1;
		editButton.setLayoutData(editButtonData);
		editButton.setText("Edit");
		editButton.setEnabled(false);
		
		removeButton = new Button(topPanel, SWT.PUSH | SWT.CENTER);
		GridData removeButtonData = new GridData(GridData.FILL_HORIZONTAL);
		removeButtonData.horizontalSpan = 1;
		removeButton.setLayoutData(removeButtonData);
		removeButton.setText("Remove");
		removeButton.setEnabled(false);
		
		// Add Listeners
		createButton.addSelectionListener(createButtonListener);
		editButton.addSelectionListener(editButtonListener);
		removeButton.addSelectionListener(removeButtonListener);
		validationViewer.addSelectionChangedListener(constraintListener);
		
		return topPanel;
	}

	
	/**
	 * Constructor of the dialog.
	 *
	 *@param parentShell the parent shell.
	 */
	public ValidationManagementDialog(Shell parentShell) {
		super(parentShell);
		server = ModelValidatorPlugin.getServer();
	}
	
	/**
	 * Internal method used to update the data in the TreeViewer showing the validations.
	 */
	private void updateValidationData () {
		Tree data = validationViewer.getTree();
		data.removeAll();
		List<IBatchValidation> validations = server.getBatchValidationRepository();
		for (IBatchValidation validation : validations) {
			TreeItem valItem = new TreeItem(data, SWT.NONE);
			valItem.setText(validation.getName());
			if (validation.getResourceType().equals(ResourceType.PROTECTED)) {
				valItem.setImage(CorePlugin.getImage(CorePlugin.VALIDATION_ICON, CorePlugin.LOCK_OVERLAY, CorePlugin.BOTTOM_RIGHT));
			}
			else if (validation.getResourceType().equals(ResourceType.NETWORKED)) {
				valItem.setImage(CorePlugin.getImage(CorePlugin.VALIDATION_ICON, CorePlugin.NET_OVERLAY, CorePlugin.BOTTOM_RIGHT));
			}
			else {
				valItem.setImage(CorePlugin.getImage(CorePlugin.VALIDATION_ICON));
			}
			valItem.setData(validation);
			for (IModelValidatorConstraint constraint : validation.getSelectedConstraints()) {
				TreeItem constItem = new TreeItem(valItem, SWT.NONE);
				constItem.setText(constraint.getName());
				switch (constraint.getSeverity()) {
				case IStatus.INFO:
					constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON, CorePlugin.INFO_OVERLAY, CorePlugin.TOP_LEFT));
					break;
				case IStatus.WARNING:
					constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON, CorePlugin.WARNING_OVERLAY, CorePlugin.TOP_LEFT));
					break;
				case IStatus.ERROR:
					constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON, CorePlugin.ERROR_OVERLAY, CorePlugin.TOP_LEFT));
					break;
				default:
					constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON));
					break;
				}
				constItem.setData(constraint);
			}
		}
		validationViewer.setSelection(TreeSelection.EMPTY);
	}

}
